﻿using UnityEngine;
using UnityEditor;
using System.Collections;
using System.IO;

[CustomEditor(typeof(MapManager))]
public class MapManagerInspector : Editor {

	public override void OnInspectorGUI () {
		MapManager mapManager = target as MapManager;
		CommonEditorUI.DrawSeparator (Color.yellow);
		DrawMinMaxValues (mapManager);
		DrawBaseTileObject (mapManager);
		DrawCurrentMinMax (mapManager);
		DrawGenerateButton (mapManager);
		CommonEditorUI.DrawSeparator (Color.cyan);
		DrawSaveLoadButton (mapManager);
		CommonEditorUI.DrawSeparator (Color.cyan);
		DrawPathData (mapManager);
		CommonEditorUI.DrawSeparator (Color.cyan);
		ShowTiles (mapManager);
	}

	void DrawSaveLoadButton (MapManager mapManager)
	{
		string fileName =
			EditorGUILayout.TextField ("Map File Name", mapManager._fileName);
		if (fileName != mapManager._fileName) 
		{
			CommonEditorUI.RegisterUndo("Map File Name", mapManager);
			mapManager._fileName = fileName;
		}

		EditorGUILayout.BeginHorizontal ();
		if (GUILayout.Button ("Save Map Data"))
		{
			//Save process
			string title = "Save Map File";
			string msg = "Do you want to save map data?";
			if (EditorUtility.DisplayDialog (title, msg, "yes", "no"))
			{
				string dataPath = Application.dataPath;
				string fullPath = dataPath + "/Resources/MapData/" + fileName + ".txt";

				FileStream fs = new FileStream(fullPath, FileMode.Create);
				TextWriter textWriter = new StreamWriter(fs);
				// == TextReader textReader = new StringReader(asset.text);

				int width = mapManager._currentWidth;
				int height = mapManager._currentHeight;
				textWriter.WriteLine("width " + width);
				textWriter.WriteLine("height " + height);

				for (int i = 0; i < width; i++)
				{
					for (int j = 0; j < height; j++ )
					{
						Transform tile = mapManager._tiles[i, j].transform;
						textWriter.Write(tile.position + "\t");
						textWriter.Write(tile.eulerAngles + "\t");

						TileInfo tileInfo = tile.GetComponent<TileInfo>();
						textWriter.Write((int)tileInfo.currentTileStyle + "\t");
						textWriter.Write("\r\n");
					}
				}

				//save path
				int pathCount = mapManager._pathList.Count;

				textWriter.WriteLine("pathCount " + pathCount);
				for (int i =0; i < pathCount; i++) 
				{
					string[] tileIndex = mapManager._pathList[i].name.Split('_');

					textWriter.Write (tileIndex[0] + "\t");
					textWriter.WriteLine (tileIndex[1]);
				}
				textWriter.Close ();
			} // End of if (EditorUtility.DisplayDialog(title, msg, "yes", "no"))
		} // End of if GUILayout.Button ("Save Map Data"))
		if (GUILayout.Button ("Load Map Data"))
		{
			//Load process
			mapManager.LoadMapDataFromFile();
		}
		EditorGUILayout.EndHorizontal ();
	}

	void DrawMinMaxValues(MapManager mapManager){
		GUI.color = (mapManager._minWidth >= 3 && mapManager._minWidth <= 20) ? Color.green : Color.red;
		int minWidth  = EditorGUILayout.IntField ("Map Min Width", mapManager._minWidth);
		if (minWidth != mapManager._minWidth) {
			CommonEditorUI.RegisterUndo("Map Min Width", mapManager);
			mapManager._minWidth = minWidth;
		}
		GUI.color = Color.white;

		GUI.color = (mapManager._minHeight >= 3 && mapManager._minHeight <= 20) ? Color.green : Color.red;
		int minHeight = EditorGUILayout.IntField ("Map Min Height", mapManager._minHeight);
		if (minHeight != mapManager._minHeight) {
			CommonEditorUI.RegisterUndo("Map Min Height", mapManager);
			mapManager._minHeight = minHeight;
		}
		GUI.color = Color.white;

		CommonEditorUI.DrawSeparator();

		GUI.color = (mapManager._maxWidth >= 3 && mapManager._maxWidth <= 20) ? Color.green : Color.red;
		int maxWidth = EditorGUILayout.IntField("Map Max Width", mapManager._maxWidth);
		if (maxWidth != mapManager._maxWidth) {
			CommonEditorUI.RegisterUndo("Map Max Width", mapManager);
			mapManager._maxWidth = maxWidth;
		}
		GUI.color = Color.white;

		GUI.color = (mapManager._maxHeight >= 3 && mapManager._maxHeight <= 20) ? Color.green : Color.red;
		int maxHeight = EditorGUILayout.IntField ("Map Min Height", mapManager._maxHeight);
		if(maxHeight!=mapManager._maxHeight){
			CommonEditorUI.RegisterUndo("Map Max Height", mapManager);
			mapManager._maxHeight = maxHeight;
		}
		GUI.color = Color.white;

		CommonEditorUI.DrawSeparator();
	}

	void DrawBaseTileObject(MapManager mapManager){
		GUI.color = (mapManager._baseTilePrefab != null) ? Color.green : Color.red;
		GameObject baseTilePrefab = (GameObject)EditorGUILayout.ObjectField (
			"Base Field", mapManager._baseTilePrefab,typeof(GameObject),true);

		if (baseTilePrefab != mapManager._baseTilePrefab) {
			CommonEditorUI.RegisterUndo("Map Base Tile",mapManager);
			mapManager._baseTilePrefab = baseTilePrefab;
		}

		GUI.color = Color.white;
	}

	void DrawCurrentMinMax(MapManager mapManager){
		GUI.color = (mapManager._currentWidth >= mapManager._minWidth 
						&& mapManager._currentWidth <= mapManager._maxWidth)
			? Color.green : Color.red;

		int width = EditorGUILayout.IntField ("Current Map Width", mapManager._currentWidth);
		if (width != mapManager._currentWidth) {
			CommonEditorUI.RegisterUndo("Current Map Width", mapManager);
			mapManager._currentWidth = width;
		}
		GUI.color = Color.white;

		GUI.color = (mapManager._currentHeight >= mapManager._minHeight &&
						mapManager._currentHeight <= mapManager._maxHeight)
			? Color.green : Color.red;

		int height = EditorGUILayout.IntField ("Current Map Height", mapManager._currentHeight);
		if (height != mapManager._currentHeight) {
			CommonEditorUI.RegisterUndo("Current Map Height", mapManager);
			mapManager._currentHeight = height;
		}
		GUI.color = Color.white;
	}

	void DrawGenerateButton(MapManager mapManager){
		EditorGUILayout.BeginHorizontal ();
		if (GUILayout.Button("Generate Map Data")) {
			mapManager.CreatTiles(mapManager);
		}
		if (GUILayout.Button ("Remove Map Data")) {
			mapManager.RemoveAllTiles();
		}
		EditorGUILayout.EndHorizontal ();
	}

	public void ShowTiles(MapManager mapManager){
		if (mapManager._tiles == null) return;
		int width = mapManager._tiles.GetLength (0);
		int height = mapManager._tiles.GetLength (1);
		EditorGUILayout.LabelField ("Tiles Width : " + width);
		EditorGUILayout.LabelField ("Tiles Height : " + height);
		for (int i=0; i<width; i++) {
			for(int j=0; j<height; j++){
				string text = string.Format("Tile ( {0}, {1} )", i, j);
				EditorGUILayout.ObjectField(text,mapManager._tiles[i,j],typeof(GameObject),true);
			}
		}
	}

    public void OnSceneGUI()
    {
        if (Application.isPlaying)
            return;

        MapManager mapManager = target as MapManager;

		Handles.BeginGUI ();
		if (GUI.Button(new Rect(10, 10, 100, 30), "Normal")) {
			mapManager._editTileStyle = TILESTYLE.NORMAL;
		}

		if (GUI.Button(new Rect(10, 50, 100, 30), "Straight")) {
			mapManager._editTileStyle = TILESTYLE.STRAIGHT;
		}

		if (GUI.Button(new Rect(10, 90, 100, 30), "Corner")) {
			mapManager._editTileStyle = TILESTYLE.CORNER;
		}

		if (GUI.Button(new Rect(10, 130, 100, 30), "Start")) {
			mapManager._editTileStyle = TILESTYLE.START;
		}

		if (GUI.Button(new Rect(10, 170, 100, 30), "End")) {
			mapManager._editTileStyle = TILESTYLE.END;
		}

		GUI.color = Color.green;
		GUI.Label (new Rect (120, 10, 500, 30), "Edit Mode : " + mapManager._editTileStyle);
		GUI.color = Color.white;
		Handles.EndGUI ();

		int ControlID = GUIUtility.GetControlID (FocusType.Passive);
		HandleUtility.AddDefaultControl (ControlID);

        Event e = Event.current;

		if (e.isKey) { // 2는 유니티에서 미리 쓰고 있는 키라서 할당을 안함 (2D - 3D 전환에 쓰임)
			if (e.character == '3')
				mapManager._editTileStyle = TILESTYLE.NORMAL;
			if (e.character == '4')
				mapManager._editTileStyle = TILESTYLE.STRAIGHT;
			if (e.character == '5')
				mapManager._editTileStyle = TILESTYLE.CORNER;
			if (e.character == '6')
				mapManager._editTileStyle = TILESTYLE.START;
			if (e.character == '7')
				mapManager._editTileStyle = TILESTYLE.END;
		}

		if (e.type == EventType.mouseDown ||
		    e.type == EventType.mouseDrag)
		{
			if (e.alt)
				return;

			Vector2 mousePosition = e.mousePosition;

			Ray ray = HandleUtility.GUIPointToWorldRay(mousePosition);

			RaycastHit hit; // 충돌체의 정보를 얻는 자료형
			bool result = Physics.Raycast(ray, out hit, 1000.0f);

			if (result) {
				GameObject tileObj = hit.transform.gameObject;

				TileInfo tileInfo = tileObj.GetComponent<TileInfo>();
				if (tileInfo == null)
					return;

				if (e.button == 0)
				{
					if (e.shift) {
						if (mapManager._pathList.Contains (hit.transform) == false)
						{
							mapManager._pathList.Add (hit.transform);
						}
					}
					else
					{
						tileInfo.currentTileStyle = mapManager._editTileStyle;
						tileInfo.UpdateMaterial();
					}
				}
				else if (e.button == 1)
				{
					if (e.shift) {
						if (mapManager._pathList.Contains (hit.transform) == true)
						{
							mapManager._pathList.Remove (hit.transform); 

						}
					}
					else 
					{
						hit.transform.localEulerAngles += new Vector3(0.0f, 90.0f, 0.0f);
					}
				}
			}
		}

		DrawPathList (mapManager);
    }

	void DrawPathList(MapManager mapManager)
	{
		for (int i = 0; i < mapManager._pathList.Count; i++) {
			Transform obj = mapManager._pathList[i]; // wayPoint

			TileInfo tileInfo = obj.GetComponent<TileInfo>();

			if (tileInfo.currentTileStyle == TILESTYLE.START)
			{
				Handles.color = Color.green;
			}
			else if (tileInfo.currentTileStyle == TILESTYLE.END)
			{
				Handles.color = Color.red;
			}
			Handles.SphereCap (i, obj.position + Vector3.up * 0.5f, obj.rotation, 0.5f);

			Handles.color = Color.white;
		}

		if (mapManager._pathList.Count >= 2) 
		{
			Handles.color = Color.magenta;

			for (int i = 0; i < mapManager._pathList.Count - 1; i++) {
				Transform obj1 = mapManager._pathList[i];
				Transform obj2 = mapManager._pathList[i + 1];

				Vector3 pos1 = obj1.position + Vector3.up * 0.5f;
				Vector3 pos2 = obj2.position + Vector3.up * 0.5f;

				Handles.DrawLine (pos1, pos2);
			}

			Handles.color = Color.white;
		}
	}

	void DrawPathData(MapManager mapManager)
	{
		if(GUILayout.Button ("Remove All Path Data"))
		{
			mapManager._pathList.Clear ();
		}

		string pathLabel = "path List : " + mapManager._pathList.Count;
		EditorGUILayout.LabelField (pathLabel);

		for (int i = 0; i < mapManager._pathList.Count; i++)
		{
			string pathName = "path Index : " + i;
			Transform pathTransform = mapManager._pathList[i];
			EditorGUILayout.ObjectField(pathName, pathTransform, typeof(GameObject), true);
		}
	}
}




















